<template>
  <div>
    <vxe-toolbar ref="toolbarRef" :refresh="{ queryMethod: searchMethod }" export print custom>
      <template #buttons>
        <vxe-button @click="insertEvent">新增</vxe-button>
      </template>
    </vxe-toolbar>

    <vxe-table show-overflow keep-source ref="tableRef" :row-config="{ keyField: 'id' }"
      :column-config="{ resizable: true }" :print-config="{}" :export-config="{}" :loading="loading"
      :tree-config="{ transform: true, rowField: 'id', parentField: 'parentId' }"
      :edit-config="{ trigger: 'click', mode: 'row', showStatus: true }" :data="tableData">
      <vxe-column type="checkbox" width="60"></vxe-column>
      <vxe-column field="menuName" title="菜单名称" tree-node></vxe-column>
      <vxe-column field="sort" title="排序" tree-node></vxe-column>
      <vxe-column field="url" title="请求地址" tree-node></vxe-column>
      <vxe-column field="visible" title="是否可见" tree-node></vxe-column>
      <vxe-column field="permission" title="权限表示" tree-node></vxe-column>
      <vxe-column title="操作" width="640">
        <template #default="{ row }">
          <vxe-button status="primary" @click="insertRow(row, 'current')">添加菜单</vxe-button>
          <vxe-button status="primary" @click="insertRow(row, 'bottom')">添加子菜单</vxe-button>
          <vxe-button status="danger" @click="removeRow(row)">删除菜单</vxe-button>
        </template>
      </vxe-column>
    </vxe-table>
  </div>
</template>

<script lang="ts" setup>
import { number } from 'echarts';
import { ref, nextTick } from 'vue'
import { VXETable, VxeTableInstance, VxeToolbarInstance } from 'vxe-table'

interface RowVO {
  id: number
  parentId: number | null
  menuName: string
  type: string
  size: number
  date: string
  sort: number
  url: string
  visible: boolean
  permission: String
}

const loading = ref(false)
const tableData = ref<RowVO[]>([])

const tableRef = ref<VxeTableInstance<RowVO>>()
const toolbarRef = ref<VxeToolbarInstance>()

const findList = () => {
  loading.value = true
  return new Promise(resolve => {
    setTimeout(() => {
      tableData.value = [
        { id: 10000, parentId: null, menuName: '菜单名称1', type: 'mp3', size: 1024, date: '2020-08-01', sort: 1, url: '/path/to/abc1', visible: true, permission: 'read' },
        { id: 10001, parentId: null, menuName: '菜单名称2', type: 'mp4', size: 0, date: '2021-04-01', sort: 2, url: '/path/to/test2', visible: true, permission: 'write' },
        { id: 10002, parentId: null, menuName: '菜单名称3', type: 'pdf', size: 2048, date: '2022-01-15', sort: 3, url: '/path/to/menu3', visible: false, permission: 'read' },
        { id: 10000, parentId: null, menuName: '菜单名称1', type: 'mp3', size: 1024, date: '2020-08-01', sort: 1, url: '/path/to/abc1', visible: true, permission: 'read' },
        { id: 10001, parentId: null, menuName: '菜单名称2', type: 'mp4', size: 0, date: '2021-04-01', sort: 2, url: '/path/to/test2', visible: true, permission: 'write' },
        { id: 10002, parentId: null, menuName: '菜单名称3', type: 'pdf', size: 2048, date: '2022-01-15', sort: 3, url: '/path/to/menu3', visible: false, permission: 'read' },
        { id: 10000, parentId: null, menuName: '菜单名称1', type: 'mp3', size: 1024, date: '2020-08-01', sort: 1, url: '/path/to/abc1', visible: true, permission: 'read' },
        { id: 10001, parentId: null, menuName: '菜单名称2', type: 'mp4', size: 0, date: '2021-04-01', sort: 2, url: '/path/to/test2', visible: true, permission: 'write' },
        { id: 10002, parentId: null, menuName: '菜单名称3', type: 'pdf', size: 2048, date: '2022-01-15', sort: 3, url: '/path/to/menu3', visible: false, permission: 'read' },
        { id: 10000, parentId: null, menuName: '菜单名称1', type: 'mp3', size: 1024, date: '2020-08-01', sort: 1, url: '/path/to/abc1', visible: true, permission: 'read' },
        { id: 10001, parentId: null, menuName: '菜单名称2', type: 'mp4', size: 0, date: '2021-04-01', sort: 2, url: '/path/to/test2', visible: true, permission: 'write' },
        { id: 10002, parentId: null, menuName: '菜单名称3', type: 'pdf', size: 2048, date: '2022-01-15', sort: 3, url: '/path/to/menu3', visible: false, permission: 'read' },
        { id: 10000, parentId: null, menuName: '菜单名称1', type: 'mp3', size: 1024, date: '2020-08-01', sort: 1, url: '/path/to/abc1', visible: true, permission: 'read' },
        { id: 10001, parentId: null, menuName: '菜单名称2', type: 'mp4', size: 0, date: '2021-04-01', sort: 2, url: '/path/to/test2', visible: true, permission: 'write' },
        { id: 10002, parentId: null, menuName: '菜单名称3', type: 'pdf', size: 2048, date: '2022-01-15', sort: 3, url: '/path/to/menu3', visible: false, permission: 'read' },
        { id: 10000, parentId: null, menuName: '菜单名称1', type: 'mp3', size: 1024, date: '2020-08-01', sort: 1, url: '/path/to/abc1', visible: true, permission: 'read' },
        { id: 10001, parentId: null, menuName: '菜单名称2', type: 'mp4', size: 0, date: '2021-04-01', sort: 2, url: '/path/to/test2', visible: true, permission: 'write' },
        { id: 10002, parentId: null, menuName: '菜单名称3', type: 'pdf', size: 2048, date: '2022-01-15', sort: 3, url: '/path/to/menu3', visible: false, permission: 'read' },
        { id: 10000, parentId: null, menuName: '菜单名称1', type: 'mp3', size: 1024, date: '2020-08-01', sort: 1, url: '/path/to/abc1', visible: true, permission: 'read' },
        { id: 10001, parentId: null, menuName: '菜单名称2', type: 'mp4', size: 0, date: '2021-04-01', sort: 2, url: '/path/to/test2', visible: true, permission: 'write' },
        { id: 10002, parentId: null, menuName: '菜单名称3', type: 'pdf', size: 2048, date: '2022-01-15', sort: 3, url: '/path/to/menu3', visible: false, permission: 'read' },
        { id: 10000, parentId: null, menuName: '菜单名称1', type: 'mp3', size: 1024, date: '2020-08-01', sort: 1, url: '/path/to/abc1', visible: true, permission: 'read' },
        { id: 10001, parentId: null, menuName: '菜单名称2', type: 'mp4', size: 0, date: '2021-04-01', sort: 2, url: '/path/to/test2', visible: true, permission: 'write' },
        { id: 10002, parentId: null, menuName: '菜单名称3', type: 'pdf', size: 2048, date: '2022-01-15', sort: 3, url: '/path/to/menu3', visible: false, permission: 'read' },
        { id: 10000, parentId: null, menuName: '菜单名称1', type: 'mp3', size: 1024, date: '2020-08-01', sort: 1, url: '/path/to/abc1', visible: true, permission: 'read' },
        { id: 10001, parentId: null, menuName: '菜单名称2', type: 'mp4', size: 0, date: '2021-04-01', sort: 2, url: '/path/to/test2', visible: true, permission: 'write' },
        { id: 10002, parentId: null, menuName: '菜单名称3', type: 'pdf', size: 2048, date: '2022-01-15', sort: 3, url: '/path/to/menu3', visible: false, permission: 'read' },
        // 更多数据...
      ]
      loading.value = false
      resolve(null)
    }, 300)
  })
}

const searchMethod = () => {
  const $table = tableRef.value
  if ($table) {
    // 清除所有状态
    $table.clearAll()
    return findList()
  }
  return Promise.resolve()
}

const insertRow = async (currRow: RowVO, locat: string) => {
  const $table = tableRef.value
  if ($table) {
    const date = new Date()
    // 如果 null 则插入到目标节点顶部
    // 如果 -1 则插入到目标节点底部
    // 如果 row 则有插入到效的目标节点该行的位置
    const rid = Date.now()
    if (locat === 'current') {
      const record = {
        name: `新数据${rid}`,
        id: rid,
        parentId: currRow.parentId, // 父节点必须与当前行一致
        date: `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`
      }
      const { row: newRow } = await $table.insertAt(record, currRow)
      await $table.setEditRow(newRow) // 插入子节点
    } else if (locat === 'top') {
      const record = {
        name: `新数据${rid}`,
        id: rid,
        parentId: currRow.id, // 需要指定父节点，自动插入该节点中
        date: `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`
      }
      const { row: newRow } = await $table.insert(record)
      await $table.setTreeExpand(currRow, true) // 将父节点展开
      await $table.setEditRow(newRow) // 插入子节点
    } else if (locat === 'bottom') {
      const record = {
        name: `新数据${rid}`,
        id: rid,
        parentId: currRow.id, // 需要指定父节点，自动插入该节点中
        date: `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`
      }
      const { row: newRow } = await $table.insertAt(record, -1)
      await $table.setTreeExpand(currRow, true) // 将父节点展开
      await $table.setEditRow(newRow) // 插入子节点
    }
  }
}

const insertNextRow = async (currRow: RowVO, locat: string) => {
  const $table = tableRef.value
  if ($table) {
    const date = new Date()
    // 如果 null 则插入到目标节点顶部
    // 如果 -1 则插入到目标节点底部
    // 如果 row 则有插入到效的目标节点该行的位置
    const rid = Date.now()
    if (locat === 'current') {
      const record = {
        name: `新数据${rid}`,
        id: rid,
        parentId: currRow.parentId, // 父节点必须与当前行一致
        date: `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`
      }
      const { row: newRow } = await $table.insertNextAt(record, currRow)
      await $table.setEditRow(newRow) // 插入子节点
    }
  }
}

const removeRow = async (row: RowVO) => {
  const $table = tableRef.value
  if ($table) {
    await $table.remove(row)
  }
}

const insertEvent = async () => {
  const $table = tableRef.value
  if ($table) {
    const date = new Date()
    const rid = Date.now()
    const record = {
      name: `新数据${rid}`,
      id: rid,
      parentId: null,
      date: `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`
    }
    const { row: newRow } = await $table.insert(record)
    await $table.setEditRow(newRow)
  }
}

const getInsertEvent = () => {
  const $table = tableRef.value
  if ($table) {
    const insertRecords = $table.getInsertRecords()
    VXETable.modal.alert(`新增：${insertRecords.length}`)
  }
}

const getRemoveEvent = () => {
  const $table = tableRef.value
  if ($table) {
    const removeRecords = $table.getRemoveRecords()
    VXETable.modal.alert(removeRecords.length)
  }
}

const getUpdateEvent = () => {
  const $table = tableRef.value
  if ($table) {
    const updateRecords = $table.getUpdateRecords()
    VXETable.modal.alert(`更新：${updateRecords.length}`)
  }
}

nextTick(() => {
  // 将表格和工具栏进行关联
  const $table = tableRef.value
  const $toolbar = toolbarRef.value
  if ($table && $toolbar) {
    $table.connect($toolbar)
  }
  findList()
})
</script>
